var TSUI;
(function (TSUI) {
    (function (Collections) {
        var List = (function () {
            function List(obj) {
                if (typeof obj === "undefined") { obj = null; }
                this.items = [];
                this.OnModified = new TSUI.Events.CollectionModifiedEvent();
                if (obj !== null) {
                    if (TSUI.isNumber(obj)) {
                        this.items = new Array(obj);
                    } else if (TSUI.isArray(obj)) {
                        this.items = (obj).slice(0);
                    } else {
                        throw new TSUI.Exceptions.ArgumentException("obj", "TSUI.Components.List:constructor", new TSUI.Exceptions.IncorrectTypeException(typeof (obj), "number or array", "TSUI.Components.List:constructor"));
                    }
                } else {
                    this.items = [];
                }
            }
            List.prototype.Add = function (object) {
                this.items.push(object);
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Add, new List([object])));
            };

            List.prototype.AddRange = function (objects) {
                this.items.push(objects.ToArray());
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Add, objects));
            };

            List.prototype.Clear = function () {
                var _thisClone = this.Clone();
                this.items = [];
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Remove, _thisClone));
            };

            List.prototype.Clone = function () {
                return new List(this.items.slice(0));
            };

            List.prototype.Concat = function (other) {
                var NewList = new List(this.Count() + other.Count());
                NewList.AddRange(this);
                NewList.AddRange(other);
                return NewList;
            };

            List.prototype.Contains = function (object) {
                return this.IndexOf(object) > -1;
            };

            List.prototype.CopyTo = function (dest, offset, count) {
                if (typeof offset === "undefined") { offset = 0; }
                if (typeof count === "undefined") { count = this.Count(); }
                dest.AddRange(this.Range(offset, count));
            };

            List.prototype.Count = function () {
                return this.items.length;
            };

            List.prototype.ElementAt = function (index) {
                if (index > -1 && index < this.Count()) {
                    return this.items[index];
                }
                return null;
            };

            List.prototype.Equals = function (object) {
                return this === object;
            };

            List.prototype.IndexOf = function (object) {
                return this.items.indexOf(object);
            };

            List.prototype.Insert = function (object, index) {
                this.items.splice(index, 0, object);
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Add, new List([object])));
            };

            List.prototype.InsertRange = function (objects, index) {
                this.items.splice(index, 0, []);
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Add, new List(objects)));
            };

            List.prototype.Range = function (index, count) {
                if (typeof count === "undefined") { count = this.Count() - index; }
                var max = Math.min(index + count, this.Count());
                return new List(this.items.slice(index, max));
            };

            List.prototype.Remove = function (object, event) {
                if (typeof event === "undefined") { event = true; }
                var index = this.IndexOf(object);
                if (index > -1) {
                    this.items.splice(index, 1);
                    if (event) {
                        this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Remove, new List([object])));
                    }
                }
            };

            List.prototype.RemoveAll = function (objects) {
                for (var i = 0; i < objects.Count(); i++) {
                    this.Remove(objects.ElementAt(i), false);
                }
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Remove, objects));
            };

            List.prototype.RemoveAt = function (index) {
                var x = this.items.splice(index, 1)[0];
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Remove, new List([x])));
                return x;
            };

            List.prototype.RemoveRange = function (index, count) {
                count = Math.min(count, this.Count());
                var ReturnList = new List(this.items.splice(index, count));
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Remove, ReturnList));
                return ReturnList;
            };

            List.prototype.Reverse = function () {
                this.items = this.items.reverse();
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Reorder, this));
            };

            List.prototype.Sort = function (comparer) {
                if (typeof comparer === "undefined") { comparer = new Collections.ToStringComparer(); }
                this.items = this.items.sort(comparer.Compare);
                this.OnModified.Invoke(new TSUI.Events.CollectionModifiedEventArgs(this, TSUI.Events.CollectionModifications.Reorder, this));
            };

            List.prototype.ToArray = function () {
                return this.items.slice(0);
            };
            return List;
        })();
        Collections.List = List;
    })(TSUI.Collections || (TSUI.Collections = {}));
    var Collections = TSUI.Collections;
})(TSUI || (TSUI = {}));
